/**
 * Copyright (C), 2015-2024, XXX有限公司
 * FileName: TargetDbThread
 * Author:   mac
 * Date:     2024/3/7 15:33
 * Description:
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.finsiot.tools.taos.migration;

import com.finsiot.tools.taos.migration.bean.DataBase;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 〈一句话功能简述〉<br> 
 * 〈〉
 *
 * @author zhangtianchang
 * @create 2024/3/7
 * @since 1.0.0
 */

@Slf4j
public class ImportData {

    private Connection connection = null;

    public ImportData(DataBase dataBase){

        connection = dataBase.createConnection();
    }


    public void importMeta(String filePath) throws SQLException, IOException {



        Statement statement= connection.createStatement();
        File file=new File(filePath+"/meta");

       File[] fileArray= file.listFiles();

        if(fileArray!=null && fileArray.length>1) {
            int sNum=0;
            int total=0;
            int num=0;
            for (File fileItem : fileArray) {

                sNum = executeSql(fileItem, statement);
               String itemName=fileItem.getName();

                log.info("导入文件:{},建超级表：{} 张,创建子表：{}",fileItem.getAbsoluteFile(),itemName.replace(".sql",""),sNum-2);
                total+=sNum-2;
                num++;
            }
            log.info("导入建超级表：{} 张,创建子表：{}",num,total);
        }
    }
    public void importData(String filePath) throws SQLException {
        long start=System.currentTimeMillis();
        // 创建固定大小的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(4);

        File file=new File(filePath+"/data");
        File[] fileArray= file.listFiles();



        if(fileArray!=null && fileArray.length>1) {

            for (File fileItem : fileArray) {
                Statement statement=connection.createStatement();
                // 提交任务到线程池执行
                executorService.execute(new RunnableTask(statement,fileItem));
            }

        }

        // 关闭线程池，以优雅的方式
        executorService.shutdown();
        try {
            // 等待线程池关闭
            executorService.awaitTermination(10000, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        long end=System.currentTimeMillis();

        long westTime=end-start;
        long seconds2= westTime/1000;

        log.info("导入数据任务创建耗时：{}分钟{}秒",(seconds2/60),(seconds2%60));
        log.info("导入数据后台进行中");
    }

    static class RunnableTask implements Runnable {

        File tablePath;
        Statement statement;

        public RunnableTask( Statement statement,File tablePath){

            this.statement=statement;
            this.tablePath=tablePath;

        }

        @Override
        public void run() {
            try {
                int sNum = 0;
                String stable = tablePath.getName();
                for (File son : tablePath.listFiles()) {
                    int num = executeBatchSql(son, statement);
                    sNum += num;
                }
                if (sNum != 0) {
                    statement.executeBatch();
                    statement.clearBatch();
                }
                statement.close();
                log.info("超级表:{} 导入数量：{}", stable, sNum);
            }catch (SQLException| IOException e){
                e.printStackTrace();
            }
        }

        private int executeBatchSql(File sqlFile,  Statement statement) throws IOException, SQLException {
            int line=0;
            FileReader fileReader=new FileReader(sqlFile);
            BufferedReader bufferedReader= new BufferedReader(fileReader);
            String tempLine;
            while ((tempLine = bufferedReader.readLine()) != null) {

                statement.addBatch(tempLine.replace(";",""));
                line++;
                if(line==20000) {
                    statement.executeBatch();
                    statement.clearBatch();
                }
            }
            bufferedReader.close();
            fileReader.close();
            return line;
        }
    }



    private int executeSql(File sqlFile, Statement statement) throws IOException {
        int line=0;
        FileReader fileReader=new FileReader(sqlFile);
        BufferedReader bufferedReader= new BufferedReader(fileReader);
        String tempLine;
        while ((tempLine = bufferedReader.readLine()) != null) {
            if(tempLine.startsWith("#")){
                continue;
            }
            try {
                statement.execute(tempLine);
                line++;
            } catch (SQLException e) {
                log.error("execute sql:{} ,exception:{}",tempLine,e.getMessage());
            }
        }
        bufferedReader.close();
        fileReader.close();

        return line;
    }
}